<template>
  <template v-for="(item, index) in layerConfig" :key="index">
    <LayerMark
      v-if="item.visible"
      :params="{
        ...commonParams,
        ...item.params,
      }"
      :hook="item.hook"
      :billboardController="billboardManager.createController(index)"
    />
  </template>
</template>

<script lang="ts" setup>
import { inject, markRaw, onUnmounted, reactive, ref, toRefs, watch } from 'vue'
import { debounce } from 'lodash'
import LayerMark from './LayerMark.vue'
import {
  usePlacementRiskMark,
  usePlacementDeviceMark,
  usePlacementEventMark,
  useBillboardClick,
} from '../hooks'
import { getViewBounds, type BillboardManager } from '../utils'
import type { DataTypeKey, LayerConfig, RequestParams } from '../types'

const props = defineProps({
  layerVisible: {
    type: Array as () => DataTypeKey[],
    default: () => [],
  },
  layerParams: {
    type: Object as () => Record<DataTypeKey, RequestParams>,
    default: () => ({}),
  },
})
const { layerVisible, layerParams } = toRefs(props)
const billboardManager = inject<BillboardManager>('billboardManager')!
const viewer = markRaw(billboardManager.viewer)
const isInitialized = ref(false)

// 公共参数
const commonParams = ref({
  queryType: 4,
  viewLimit: 5,
  ...getViewBounds(viewer),
})

const layerConfig = reactive<
  Record<DataTypeKey, Omit<LayerConfig, 'billboardController'> & { visible: boolean }>
>({
  risk: {
    params: {},
    visible: false,
    hook: usePlacementRiskMark,
  },
  device: {
    params: {},
    visible: false,
    hook: usePlacementDeviceMark,
  },
  event: {
    params: {},
    visible: false,
    hook: usePlacementEventMark,
  },
})

const debounceFn = debounce(() => {
  if (!isInitialized.value) {
    isInitialized.value = true
    return
  }
  const bounds = getViewBounds(viewer)
  if (!bounds) return
  commonParams.value = {
    ...commonParams.value,
    ...bounds,
  }
}, 300)

// 监听layerVisible变化，更新layerConfig的visible状态
watch(
  layerVisible,
  (newVisibleLayers) => {
    Object.keys(layerConfig).forEach((key) => {
      layerConfig[key as DataTypeKey].visible = newVisibleLayers.includes(key as DataTypeKey)
    })
  },
  { immediate: true }
)

// 监听layerParams变化，更新layerConfig的params
watch(
  layerParams,
  (newParams) => {
    Object.keys(newParams).forEach((key) => {
      if (layerConfig[key as DataTypeKey]) {
        layerConfig[key as DataTypeKey].params = newParams[key as DataTypeKey]
      }
    })
  },
  { deep: true, immediate: true }
)

// 相机移动结束时触发
viewer.camera.moveEnd.addEventListener(debounceFn)

// 添加点击事件
useBillboardClick(billboardManager)

// 组件卸载时移除事件监听
onUnmounted(() => {
  viewer.camera.moveEnd.removeEventListener(debounceFn)
  Object.values(layerConfig).forEach((item) => {
    item.visible = false
  })
})
</script>
